import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Board extends JPanel implements ActionListener
{
	// public int[] state = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	/**
	 * 
	 */
	final int rows = 3;
	final int cols = 3;
	int globalX = 0;
	int globalY = 0;
	int playerPiece = 1;
	int turn = 1;// player 1 turn, player 2 turn is 2
	public JButton[] buttons = new JButton[9];
	TTTGame thisGame = new TTTGame();

	// genetic player must have access to the game to do it's thing
	GeneticPlayer enemy = new GeneticPlayer(thisGame); // thisGame must exist

	// before this can be
	// created

	public Board()
	{
	}

	public Board(GeneticPlayer p)
	{
		enemy = p;
	}

	@Override
	public void paint(Graphics g)
	{
		super.paint(g);
		this.setLayout(new GridLayout(3, 3));
		Graphics2D graphic = (Graphics2D) g;
		drawState(graphic);
	}

	// this is what happens on a button click.
	@Override
	public void actionPerformed(ActionEvent e)
	{
		JButton button = (JButton) e.getSource();
		button.getParent().repaint();
		int buttonX = button.getX();
		int buttonY = button.getY();
		int blockNum = blockCalc(buttonX, buttonY);

		if (turn == 1)
		{
			// call game logic
			if (thisGame.placePiece(blockNum, playerPiece))
			{
				// alright, yay, the piece has been placed
				turn = 2;
			}
			else
			{
				// the piece can not be placed :(
				// try to notify the player somehow
				new popupNotice(0, 0, "Can't move here!").start();
			}

			// test for win, test for cat?
			if (thisGame.win(playerPiece))
			{
				// do some win condition stuff
			}
		}

		// redraw the board just to be safe
		this.invalidate();

		if (turn == 2)
		{
			if (enemy.makeMove())
			{
				turn = 1;
			}
			else
			{
				// that was a bad move, try again
			}
			// now let the AI take a turn
			// enemy.makeMove();
			// turn = 1;

			// test for win, test for cat?
			if (thisGame.win(GeneticPlayer.playerPiece))
			{
				// do some win condition stuff
				// popup a window thing
				new popupNotice(40, 40, "GeneticAlgorithm WINS!").start();
				// start a new game
			}
		}

		new popupNotice(0, 40, String.valueOf(thisGame.boardState())).start();

		// redraw the board just to be safe
		this.invalidate();
	}

	public void drawState(Graphics2D graphic)
	{

		// get the size of the window to render properly
		Dimension size = this.getSize();
		double width = size.getWidth();
		double height = size.getHeight();
		int blockWidth = (int) width / cols;
		int blockHeight = (int) height / rows;

		// draw an intial background
		graphic.setBackground(Color.white);
		graphic.clearRect(0, 0, (int) width, (int) height);

		// draw circles and Xs based on the state
		for (int i = 0; i < 9; i++)
		{

			int startX = ((i % cols) * (blockWidth)) + 7;
			int stopX = (((i % cols) + 1) * (blockWidth)) - 7;
			int startY = ((i / rows) * (blockHeight)) + 7;
			int stopY = (((i / rows) + 1) * (blockHeight)) - 7;

			// add a button for this square
			if (buttons[i] == null)
			{
				buttons[i] = new JButton();
				buttons[i].addActionListener(this);
				buttons[i].setBounds(startX, startY, blockWidth - 14,
						blockHeight - 14);
				buttons[i].setContentAreaFilled(false);
				this.add(buttons[i]);
				buttons[i].getParent().repaint();
			}
			// make sure to redraw the screen a lot
			this.revalidate();

			// draw the X or O for this square
			switch (thisGame.state[i])
			{
			case 0:
				// don't draw anything
				break;
			case 1:
				// draw X
				graphic.setColor(Color.blue);
				graphic.setStroke(new BasicStroke(5));
				graphic.drawLine(startX, startY, stopX, stopY);
				graphic.drawLine(startX, stopY, stopX, startY);
				break;
			case 2:
				// draw O
				graphic.setColor(Color.red);
				graphic.setStroke(new BasicStroke(5));
				graphic.drawArc(startX, startY, blockWidth - 14,
						blockHeight - 14, 0, 360);
				break;

			default:
				break;
			}
		}

		// draw the TTT lines on top of the shapes to hide overlaps and stuff
		for (int i = 0; i <= 3; i++)
		{
			graphic.setColor(Color.black);
			graphic.setStroke(new BasicStroke(7));
			graphic.drawLine((i * blockWidth), 0, (i * blockWidth),
					(int) (i * height));
			graphic.drawLine(0, (i * blockHeight), (int) width,
					(i * blockHeight));
		}
		// line down the left side
		graphic.drawLine(0, 0, 0, (int) height);
	}

	// returns the board place clicked on
	public int blockCalc(int x, int y)
	{
		// get the size of the window to render properly
		globalX = x;
		globalY = y;
		Dimension size = this.getSize();
		double width = size.getWidth();
		double height = size.getHeight();
		int blockWidth = (int) width / 3;
		int blockHeight = (int) height / 3;
		int retval = 0;
		int count = 0;

		// try each one until the result is found
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				if (x == j * blockWidth && y == i * blockHeight)
				{
					retval = count;
				}
				count++;
			}
		}
		return retval;
	}
}
